Skip to main content

Memory Providers

Memory providers define where and how BindAI stores and retrieves memory. BindAI separates memory operations from storage through the MemoryProvider abstraction. A Memory instance delegates storage and retrieval operations to its configured provider. This allows application code to use a consistent memory API while choosing an appropriate storage implementation.

Why Memory Providers?

Different applications require different persistence and retrieval characteristics. For example:
  • In-memory storage is useful for development and testing.
  • SQLite provides local persistent storage.
  • PostgreSQL provides persistent relational storage.
  • Vector memory supports vector-oriented retrieval.
  • Pinecone provides managed vector storage.
  • Chroma provides vector-oriented storage and retrieval.
The application interacts with the Memory abstraction rather than depending directly on a storage backend.

Architecture

The Memory class provides the application-facing API. The configured provider implements the storage and retrieval behavior.

Available Providers

BindAI currently provides the following memory providers:
  • InMemoryProvider
  • SQLiteMemoryProvider
  • PostgreSQLMemoryProvider
  • VectorMemoryProvider
  • PineconeMemoryProvider
  • ChromaMemoryProvider
All providers integrate with the common MemoryProvider abstraction. A provider can be selected directly:

In-Memory Provider

InMemoryProvider stores memory records in the running Python process.
This provider is useful for:
  • Development
  • Testing
  • Examples
  • Temporary application state
Because the records are held in process memory, they are not persisted when the process terminates.

SQLite Provider

SQLiteMemoryProvider provides persistent local storage using SQLite.
SQLite is useful when memory should survive application restarts without requiring a separate database server. Typical use cases include:
  • Local applications
  • Desktop applications
  • Prototypes
  • Small deployments
  • Development environments requiring persistence

PostgreSQL Provider

PostgreSQLMemoryProvider stores memory records in PostgreSQL. For example:
Connection information should normally be supplied through secure application configuration or environment variables rather than hard-coded credentials. PostgreSQL is useful when an application requires:
  • Persistent server-side storage
  • Shared storage across application processes
  • Relational database infrastructure
  • Structured metadata storage
  • Namespace-aware memory persistence
The provider supports the standard memory operations exposed by the memory abstraction.

Vector Memory Provider

VectorMemoryProvider is designed for vector-oriented memory storage and retrieval.
Vector memory is useful when records need to participate in similarity-oriented retrieval rather than relying only on exact keys or ordinary text matching. Typical use cases include:
  • Semantic memory
  • Similarity search
  • Embedding-based retrieval
  • Applications working with collections of vectorized memories
The exact behavior depends on the vector-memory implementation and embedding configuration.

Pinecone Provider

PineconeMemoryProvider provides managed vector-backed memory using Pinecone.
The provider can use the PINECONE_API_KEY environment variable for authentication. For example:
An API key can also be supplied explicitly when supported by the provider configuration:
For production applications, environment variables or another secure secret-management mechanism are preferable to hard-coded credentials. Pinecone-backed memory uses vector representations for semantic retrieval. The configured embedding model and the Pinecone index must use compatible dimensions. Pinecone is useful for:
  • Semantic memory
  • Similarity search
  • Managed vector storage
  • Larger memory collections
  • Cloud-based retrieval infrastructure

Chroma Provider

ChromaMemoryProvider provides Chroma-backed vector memory.
Chroma is useful for applications that need vector-oriented memory storage and retrieval. Typical use cases include:
  • Local vector memory
  • Semantic retrieval
  • Development and experimentation
  • Applications using embedding-based memory
The exact Chroma configuration depends on how the Chroma deployment is being used.

Namespaces

Memory records can be separated using namespaces.
Memory operations can target a specific namespace:
Namespaces provide a simple way to isolate groups of records. They can be useful for:
  • Users
  • Conversations
  • Tenants
  • Agents
  • Projects
  • Applications
Provider behavior may differ internally, but the namespace remains part of the BindAI memory model.

Searching Memory

The Memory abstraction exposes a common search() operation. For example:
The exact retrieval behavior depends on the configured provider. For example:
  • InMemoryProvider performs provider-specific in-memory retrieval.
  • SQLiteMemoryProvider searches locally persisted records.
  • PostgreSQLMemoryProvider performs database-backed retrieval.
  • VectorMemoryProvider provides vector-oriented retrieval.
  • PineconeMemoryProvider provides managed vector search.
  • ChromaMemoryProvider provides Chroma-backed vector retrieval.
The common interface allows application code to request memory without depending directly on a specific backend.

Metadata Filtering

Memory searches can optionally provide metadata filters where supported. For example:
Metadata filtering behavior depends on the provider. For database-backed providers, metadata can be stored and filtered according to the provider implementation. For vector databases such as Pinecone or Chroma, filtering capabilities depend on the backend’s supported metadata model and the BindAI provider implementation. Applications should therefore avoid assuming that every provider supports identical filtering semantics.

Memory Provider Interface

Memory providers implement the common MemoryProvider abstraction. The core memory operations include:
The Memory abstraction exposes these operations to application code. For example:
Or:
This keeps most application code independent of the underlying storage implementation.

Memory Records

Providers store MemoryRecord objects. A record contains a key, value, namespace, and additional memory information.
A record can also contain:
  • Memory type
  • Metadata
  • Importance
  • Access count
  • Expiration
  • Tags
  • Source
  • Relationships
  • Timestamps
  • Embeddings
  • Search score
For example:
The exact fields available are defined by MemoryRecord.

Persistence Comparison

The distinction between persistence and retrieval is important. A provider can be persistent while using a particular retrieval strategy, such as relational or vector search.

Choosing a Provider

InMemoryProvider

Use InMemoryProvider when memory only needs to exist during the current process. Good for:
  • Development
  • Testing
  • Examples
  • Temporary state

SQLiteMemoryProvider

Use SQLiteMemoryProvider when persistent local storage is required. Good for:
  • Local applications
  • Desktop applications
  • Prototypes
  • Small persistent deployments

PostgreSQLMemoryProvider

Use PostgreSQLMemoryProvider when persistent server-side relational storage is required. Good for:
  • Server applications
  • Multi-process applications
  • Existing PostgreSQL infrastructure
  • Persistent metadata-rich memory

VectorMemoryProvider

Use VectorMemoryProvider when vector-oriented memory storage or similarity-based retrieval is required. Good for:
  • Semantic memory
  • Similarity search
  • Embedding-based retrieval

PineconeMemoryProvider

Use PineconeMemoryProvider when managed vector storage and semantic retrieval are required. Good for:
  • Semantic memory
  • Larger memory collections
  • Cloud applications
  • Embedding-based retrieval
  • Managed vector infrastructure

ChromaMemoryProvider

Use ChromaMemoryProvider when Chroma-backed vector memory is appropriate. Good for:
  • Local vector applications
  • Semantic retrieval
  • Prototyping
  • Embedding-based memory

Switching Providers

Because providers implement the same memory abstraction, application-level memory code can generally remain the same when changing storage backends. For example:
The application can instead configure SQLite:
Or PostgreSQL:
The rest of the application can continue using the Memory API:
Provider-specific configuration and search behavior may still differ.

Provider Registry

BindAI includes MemoryRegistry for provider registration and lookup. For example:
A custom provider can be registered under a name:
It can then be resolved through the registry:
A registered provider can also be removed:
The registry makes the memory system extensible and allows applications to work with provider implementations by name.

Custom Providers

Applications can implement custom memory providers by implementing the MemoryProvider abstraction. A provider needs to support the core memory operations required by the interface:
A custom provider can then be registered:
This allows an application to integrate its own storage system while continuing to use the standard Memory API. A custom provider should preserve the expected semantics of MemoryRecord, namespaces, search parameters, and result handling.

Provider-Specific Behavior

Although providers share a common interface, they do not necessarily implement identical storage internals. For example:
This means application code should depend on the common API while remaining aware of provider-specific capabilities when using advanced features.

Embeddings and Vector Providers

Vector-oriented providers depend on compatible embedding representations. Conceptually:
The embedding dimensions must be compatible with the selected vector storage configuration. This is particularly important for managed vector stores such as Pinecone. If an application changes its embedding model, it may need to use a compatible index or re-embed existing records.

Memory Providers and Agents

Memory providers can be used through an agent’s memory configuration. For example:
The agent interacts with the Memory abstraction rather than needing to know which storage provider is underneath.

Resource Management

Providers that own external resources should be closed appropriately. The Memory abstraction supports closing its underlying provider:
Memory can also be used as a context manager:
This is particularly useful for providers that maintain database connections or other external resources.

Security and Configuration

Persistent memory can contain sensitive application information. Provider configuration should therefore follow normal application security practices. Avoid:
in committed application source code. Prefer secure configuration through environment variables or a secret-management system. For example:
Applications should also enforce appropriate authorization around memory operations. A memory provider is a storage mechanism, not an authorization boundary.

Best Practices

  • Choose the provider based on required persistence and retrieval behavior.
  • Use InMemoryProvider for temporary development and testing state.
  • Use SQLiteMemoryProvider for local persistent storage.
  • Use PostgreSQLMemoryProvider for shared relational persistence.
  • Use VectorMemoryProvider for vector-oriented memory.
  • Use PineconeMemoryProvider for managed semantic vector retrieval.
  • Use ChromaMemoryProvider for Chroma-backed vector memory.
  • Keep application code dependent on Memory rather than provider-specific implementations where possible.
  • Use namespaces to isolate logical groups of memory.
  • Use metadata for structured record information.
  • Use tags and relationships when records require additional organization.
  • Keep embedding dimensions compatible with vector storage.
  • Treat provider-specific search behavior as provider-dependent.
  • Use MemoryRegistry when custom or dynamically selected providers are required.
  • Keep credentials out of source code.
  • Protect memory access with appropriate authorization.
  • Close providers when they own external resources.
  • Test providers independently from model-provider behavior.

Summary

BindAI currently provides six memory provider implementations:
  • InMemoryProvider
  • SQLiteMemoryProvider
  • PostgreSQLMemoryProvider
  • VectorMemoryProvider
  • PineconeMemoryProvider
  • ChromaMemoryProvider
All providers integrate through the common MemoryProvider abstraction. Applications interact primarily with Memory, while the configured provider handles storage and retrieval. This separation allows the same application-level memory API to work with local, relational, and vector-oriented storage systems. Provider-specific capabilities can differ, particularly for search, metadata filtering, persistence, and vector retrieval. Applications should therefore rely on the common API for portable behavior and use provider-specific features deliberately when needed.